package protocols;

import java.util.HashMap;

import peer.Connection;
import peer.Message;
import peer.MessageHandler;
import peer.Peer;

public abstract class Protocol<T extends Enum<?>, S extends Enum<?>>  implements Runnable{
	
	protected final String name;
	protected Connection conn = null;
		public Connection getConnection() { return this.conn; }
		public void setConnection(Connection _conn) { this.conn = _conn; }
	
	protected Peer callback; 
		public Peer getCallback() { return callback; }
		
		
	public S state;
		public S getState() { return state; }
		public void setState(S state) { this.state = state; }
	
	protected boolean stopped = false;
		
	protected HashMap<S,MessageHandler> states = new HashMap<S,MessageHandler>();
	

	protected Protocol()  {
		name = "Protocol";		
	}
	
	protected Protocol(Connection _conn) {
		name = "Protocol";
		this.conn = _conn;
		this.callback = conn.getCallback();
		System.out.println("\tis callback null? " + (callback == null));
		conn.registerProtocol(this.getName(), this);
	}
	
	
	public abstract String getName();
	
	protected void addHandler(S state, ProtocolState<S> handler) {
		states.put(state,handler);
	}
	
	public void handle(Message<?> m) {		
		states.get(state).handle(m, conn);		
	}

	public void run() {
		Message<?> m;
		while (!stopped) {
			System.out.println("Protocol polling for messages...");
			m = (Message<?>)conn.read(getName());
			handle(m);
		}
	}
	
	public void stop() {
		this.stopped = true;		
	}
	
}
